// Copyright 2025 Code Philosophy
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

﻿using CommandLine;

namespace DeobfuscateStackTrace
{
    internal class Program
    {
        private class CommandOptions
        {

            [Option('m', "mappingFile", Required = true, HelpText = "mapping xml file")]
            public string MappingFile { get; set; }

            [Option('i', "input", Required = true, HelpText = "input obfuscated log file")]
            public string InputFile { get; set; }

            [Option('o', "output", Required = true, HelpText = "output deobfuscated log file")]
            public string OutputFile { get; set; }

            [Option('r', "removeMethodGeneratedByObfuz", HelpText = "Remove methods generated by obfuscator (e.g. '$Obfuz$ProxyCall:$Obfuz$ProxyCall$Dispatch')")]
            public bool RemoveMethodGeneratedByObfuz { get; set; }

        }

        static void Main(string[] args)
        {
            CommandOptions opt = ParseArgs(args);

            if (!File.Exists(opt.MappingFile))
            {
                Console.Error.WriteLine($"Mapping file {opt.MappingFile} not found");
                Environment.Exit(1);
            }
            if (!File.Exists(opt.InputFile))
            {
                Console.Error.WriteLine($"Input file {opt.InputFile} not found");
                Environment.Exit(1);
            }
            var reader = new SymbolMappingReader(opt.MappingFile);
            StackTraceDeObfuscator.Convert(reader, opt.InputFile, opt.OutputFile, opt.RemoveMethodGeneratedByObfuz);
        }

        private static CommandOptions ParseArgs(string[] args)
        {
            var helpWriter = new StringWriter();
            var parser = new Parser(settings =>
            {
                settings.AllowMultiInstance = true;
                settings.HelpWriter = helpWriter;
            });

            var result = parser.ParseArguments<CommandOptions>(args);
            if (result.Tag == ParserResultType.NotParsed)
            {
                Console.Error.WriteLine(helpWriter.ToString());
                Environment.Exit(1);
            }
            return ((Parsed<CommandOptions>)result).Value;
        }
    }
}
